package com.weilele.mvvm.view

import android.content.Context
import android.util.AttributeSet
import android.util.SparseArray
import android.view.View
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.core.util.containsValue
import androidx.core.view.children
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.weilele.mvvm.utils.activity.dip
import com.weilele.mvvm.utils.activity.getActivity
import com.weilele.mvvm.utils.activity.onClick
import com.weilele.mvvm.utils.glide.downloadBitmapByGlide
import com.weilele.mvvm.utils.glide.setImageGlide
import com.weilele.mvvm.utils.safeGet
import com.weilele.mvvm.widget.BaseFrameLayout
import kotlinx.coroutines.launch

open class NineImageLayout : BaseFrameLayout {
    private val tempViews = SparseArray<View>()

    /**
     * 横向间隔
     */
    var horizontalSpace = dip(4)

    /**
     * 竖向间隔
     */
    var verticalSpace = horizontalSpace

    /**
     * 每行最多几个子view
     */
    var maxPerLine = 3

    /**
     * 只有一个子view，支持自由布局
     * true，可以根据 图片尺寸，更改长宽
     * false：按照九宫格方式布局
     */
    var oneViewFreeLayout = true

    /**
     * 图片加载的占位图
     */
    @DrawableRes
    var placeholderRes: Int? = null

    /**
     * 创建子view的监听
     */
    var onCreateViewListener: Function1<Context, View>? = null

    /**
     * 子view点击监听
     */
    var onViewClickListener: Function3<View, MutableList<String>, Int, Unit>? = null

    /**
     * 绑定数据的监听
     */
    var onBindViewListener: Function4<View, MutableList<String>, String, Int, Unit>? = null

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val count = childCount
        if (count == 0) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
            return
        }
        if (!oneViewFreeLayout || childCount > 1) {
//            val widthMode = MeasureSpec.getMode(widthMeasureSpec)
//            val heightMode = MeasureSpec.getMode(heightMeasureSpec)
            val widthSize = MeasureSpec.getSize(widthMeasureSpec)
//            val heightSize = MeasureSpec.getSize(heightMeasureSpec)
            val sideLength = getSideLength(widthSize)
            //总行数，从0开始
            val numberOfLines = (childCount - 1) / maxPerLine
            val newHeight = numberOfLines * (sideLength + verticalSpace) + sideLength
            setMeasuredDimension(widthSize, newHeight)
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        }
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        if (changed) {
            when (childCount) {
                1 -> {
                    if (oneViewFreeLayout) {
                        val view = getChildAt(0)
                        view.layout(0, 0, view.measuredWidth, view.measuredHeight)
                    } else {
                        layoutChild(l, t, r, b)
                    }
                }
                else -> {
                    layoutChild(l, t, r, b)
                }
            }
        }
    }

    private fun layoutChild(l: Int, t: Int, r: Int, b: Int) {
        children.forEachIndexed { index, view ->
            //行数 从0开始
            val numberOfLines = (index / maxPerLine)
            //列数 从0开始
            val numberOfColumns = index % maxPerLine
            //计算view的宽高
            val sideLength = getSideLength(r - l)
            val left = numberOfColumns * (sideLength + horizontalSpace)
            val top = numberOfLines * (sideLength + verticalSpace)
            val right = left + sideLength
            val bottom = top + sideLength
            view.layout(left, top, right, bottom)
        }
    }

    /**
     * 获取view的平均宽度
     */
    private fun getSideLength(width: Int): Int {
        return (width - horizontalSpace * (maxPerLine - 1)) / maxPerLine
    }

    /**
     * 如果不拦截view，
     */
    private var _datas: MutableList<String>? = null
    fun setDatas(
        datas: MutableList<String>?,
        ivOneWidth: Int = 0,
        ivOneHeight: Int = 0,
        maxOneWidth: Int = 0,
        maxOneHeight: Int = 0
    ) {
        this._datas = datas
        if (datas.isNullOrEmpty()) {
            removeAllViews()
        } else {
            if (childCount > datas.count()) {
                val size = childCount - datas.count()
                removeViews(datas.count(), size)
            }
            when (datas.count()) {
                1 -> {
                    if (oneViewFreeLayout) {
                        setOneView(
                            ivOneWidth,
                            ivOneHeight,
                            maxOneWidth,
                            maxOneHeight
                        )
                    } else {
                        setOtherView()
                    }
                }
                else -> {
                    setOtherView()
                }
            }
        }
    }

    private fun setOtherView() {
        val datas = _datas ?: return
        val count = childCount
        datas.forEachIndexed { index, data ->
            val view = getView(index, count)
            val listener = onBindViewListener
            if (listener == null) {
                view.safeGet<ImageView>()?.setImageGlide(data, placeholderRes, placeholderRes)
            } else {
                listener.invoke(view, datas, data, index)
            }
            if (view.parent == null) {
                this@NineImageLayout.addView(view)
            }
        }
    }


    /**
     *  url 图片地址
     *  ivWidth 图片宽度，不知道可以不写，默认0
     *  ivHeight 图片高度，不知道可以不写，默认0
     *  maxWidth 限制图片的最大宽度
     *  maxHeight 限制图片的最大高度
     */
    private fun setOneView(
        ivWidth: Int = 0,
        ivHeight: Int = 0,
        maxWidth: Int = 0,
        maxHeight: Int = 0
    ) {
        val datas = _datas ?: return
        val url = datas.firstOrNull() ?: return
        val listener = onBindViewListener
        if (ivHeight == 0 || ivWidth == 0) {
            getActivity()?.also {
                it.lifecycleScope.launch {
                    val bitmap = it.downloadBitmapByGlide(url).result
                    if (bitmap != null) {
                        val view =
                            addOneView(bitmap.width, bitmap.height, maxWidth, maxHeight)
                        if (listener == null) {
                            view.safeGet<ImageView>()?.setImageBitmap(bitmap)
                        } else {
                            listener.invoke(view, datas, url, 0)
                        }
                    }
                }
            }
        } else {
            val view = addOneView(ivWidth, ivHeight, maxWidth, maxHeight)
            if (listener == null) {
                view.safeGet<ImageView>()?.setImageGlide(url, placeholderRes, placeholderRes)
            } else {
                listener.invoke(view, datas, url, 0)
            }
        }
    }

    /**
     * 根据参数，设置只有一张图片时候，view的显示
     */
    private fun addOneView(
        ivWidth: Int,
        ivHeight: Int,
        maxWidth: Int,
        maxHeight: Int,
    ): View {
        var viewMaxW = maxWidth
        var viewMaxH = maxHeight
        if (maxWidth == 0 || maxHeight == 0) {
            viewMaxW = dip(240)
            viewMaxH = dip(240)
        }
        //view宽高比的一个分隔值
        val viewRatio = viewMaxW / viewMaxH.toFloat()
        val view = getView(0, childCount)
        var realW = 0
        var realH = 0
        val bitmapRatio = ivWidth.toFloat() / ivHeight
        when {
            bitmapRatio <= viewRatio -> {
                //高度固定，根据图片尺寸，缩放宽度
                realH = viewMaxH
                realW = (realH * bitmapRatio).toInt()
            }
            else -> {
                //宽度固定，根据图片尺寸，缩放高度
                realW = viewMaxH
                realH = (realW / bitmapRatio).toInt()
            }
        }
        val lp = LayoutParams(realW, realH)
        this@NineImageLayout.addView(view, lp)
        return view
    }

    /**
     * 获取缓存的view，并且添加到布局中
     */
    private fun getView(position: Int, viewCount: Int): View {
        if (position < viewCount) {
            return getChildAt(position)
        }
        var tempView: ImageView? = null
        val count = tempViews.size()
        for (index in 0 until count) {
            val value = tempViews.valueAt(index)
            if (value is ImageView && value.parent == null) {
                tempView = value
                break
            }
        }
        val view = tempView ?: createImageView().apply {
            this.onClick {
                _datas?.let {
                    onViewClickListener?.invoke(this, it, indexOfChild(this))
                }
            }
        }
        if (!tempViews.containsValue(view)) {
            tempViews.append(tempViews.size(), view)
        }
        if (view.id == NO_ID) {
            view.id = View.generateViewId()
        }
        return view
    }

    /**
     * 创建view对象
     */
    private fun createImageView(): View {
        return onCreateViewListener?.invoke(context) ?: ImageView(context)
    }
}